package world.edges;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import be.kuleuven.cs.som.annotate.Basic;

import world.Observer;
import world.square.Subject;

/**
 * Class representing a door on a border
 * 
 * @author Wim Marynissen, Frederic Mes
 * @version 1.0
 */
public class Door extends BorderElement implements Subject{

	/**
	 * Construct a door.
	 * @param	isClosed
	 * 			Indicates if the door is closed.
	 * @post	The boolean, indicating if the door is closed, is initialised.
	 * 			| new.isClosed() == isClosed
	 */
	public Door(boolean isClosed) {
		this.isClosed = isClosed;
	}

	/**
	 * Returns if the door in the wall is closed.
	 */
	@Basic
	public boolean isClosed() {
		return isClosed;
	}

	/**
	 * Change the state of the door.
	 * @param 	isClosed
	 *        	Boolean to indicate that the door should be closed or opened.
	 * @post	The new value for the boolean is equal to isClosed.
	 * 			| new.isClosed() == isClosed
	 */
	public void setClosed(boolean isClosed) {
		this.isClosed = isClosed;
		notifyObservers();
	}

	/**
	 * Variable indicating if the door is closed.
	 */
	private boolean isClosed;

	/**
	 * Open the door.
	 * @post	The new value for the boolean indication the state of the door is false.
	 * 			| new.isClosed() == false
	 */
	public void open(){
		setClosed(false);
	}
	
	/**
	 * Close the door.
	 * @post	The new value for the boolean indication the state of the door is true.
	 * 			| new.isClosed() == true
	 */
	public void close(){
		setClosed(true);
	}
	
	/**
	 * Check if the door is an obstacle.
	 * @return	True if the door is closed
	 * 			| result == isClosed()
	 */
	@Override
	public boolean isObstacle() {
		return isClosed();
	}

	
	/** 
	 * Number used to determine which border element to keep when borders are shared.
	 */
	@Override
	public int getImportanceInSharing() {
		if (isClosed())
			return 99;
		return 98;
	}
	
	
	/**
	 * Add an observer in order to know when the square's state has been changed.
	 * Method used in the ObjectObserver pattern.
	 */
	public void addObserver(Observer o) {
		observers.add(o);		
	}

	/**
	 * Remove an observer from this subject.
	 * Method used in the ObjectObserver pattern.
	 */
	public void removeObserver(Observer o) {
		observers.remove(o);		
	}
	
	public void notifyObservers() {
		   Iterator<Observer> i = observers.iterator();
		   while (i.hasNext()) {
		     Observer o = (Observer) i.next();
		     o.update(this);
		   }
		 }
	
	private List<Observer> observers = new ArrayList<Observer>();
	
	

}
